#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>

int main() {
    cv::Mat mat1, mat2;
    mat1.create(8, 8, CV_8UC3);
    mat2.create(8, 8, CV_8UC3);
    cv::randu(mat1, cv::Scalar::all(0), cv::Scalar::all(255));
    cv::randu(mat2, cv::Scalar::all(0), cv::Scalar::all(255));
    std::cout << "mat1 = \n" << mat1 << std::endl << std::endl;
    std::cout << "mat2 = \n" << mat2 << std::endl << std::endl;

    double alpha = 0.3;
    double beta = 0.5;  // if beta = 1.0 - alpha, it is linear blending
    cv::Mat result1;
    cv::addWeighted(mat1, alpha, mat2, beta, 0, result1);
    std::cout << "result1 =\n" << result1 << std::endl << std::endl;

    cv::Mat result2(8, 8, CV_8UC3);
    for (int i = 0; i < 8; i++) {
        cv::Vec3b* p1 = mat1.ptr<cv::Vec3b>(i);
        cv::Vec3b* p2 = mat2.ptr<cv::Vec3b>(i);
        cv::Vec3b* p = result2.ptr<cv::Vec3b>(i);
        for (int j = 0; j < 8; j++) {
            p[j][0] = cv::saturate_cast<uchar>(p1[j][0] * alpha + p2[j][0] * beta);  
            p[j][1] = cv::saturate_cast<uchar>(p1[j][1] * alpha + p2[j][1] * beta);
            p[j][2] = cv::saturate_cast<uchar>(p1[j][2] * alpha + p2[j][2] * beta);
        }
    }
    std::cout << "result2 = \n" << result2 << std::endl << std::endl;

    cv::Mat diff;
    diff = result1 - result2;
    std::cout << "diff = \n" << diff << std::endl << std::endl;

    cv::Mat img1 = cv::imread("/home/xlll/Downloads/opencv/samples/data/orange.jpg", cv::IMREAD_COLOR);
    cv::Mat img2 = cv::imread("/home/xlll/Downloads/opencv/samples/data/lena.jpg", cv::IMREAD_COLOR);
    cv::Mat blend;
    alpha = 0.5;
    beta = 0.5;
    cv::addWeighted(img1, alpha, img2, beta, 0, blend);
    cv::namedWindow("Blend", cv::WINDOW_AUTOSIZE);
    cv::imshow("Blend", blend);
    cv::waitKey(0);

    return EXIT_SUCCESS;
}
         
